class QuickSort {
    constructor() {
        this.numbers = [];
        this.isRunning = false;
        this.currentStep = 0;
        this.isAutoSorting = false;
        this.steps = [];
        this.currentStepIndex = 0;
        
        this.initializeElements();
        this.bindEvents();
    }

    initializeElements() {
        this.container = document.getElementById('numbersContainer');
        this.currentStepDisplay = document.getElementById('currentStep');
        this.generateNewBtn = document.getElementById('generateNew');
        this.startSortBtn = document.getElementById('startSort');
        this.nextStepBtn = document.getElementById('nextStep');
        this.resetBtn = document.getElementById('reset');
    }

    bindEvents() {
        this.generateNewBtn.addEventListener('click', () => this.generateNumbers());
        this.startSortBtn.addEventListener('click', () => this.startSort());
        this.nextStepBtn.addEventListener('click', () => this.nextStep());
        this.resetBtn.addEventListener('click', () => this.reset());
    }

    generateNumbers() {
        this.numbers = [];
        for (let i = 0; i < 6; i++) {
            this.numbers.push(Math.floor(Math.random() * 99) + 1);
        }
        this.reset();
        this.renderNumbers();
    }

    renderNumbers() {
        this.container.innerHTML = '';
        this.numbers.forEach((num, index) => {
            const box = document.createElement('div');
            box.className = 'number-box';
            box.textContent = num;
            this.container.appendChild(box);
        });
    }

    async startSort() {
        if (this.isRunning) return;
        this.isRunning = true;
        this.isAutoSorting = true;
        this.startSortBtn.disabled = true;
        this.generateNewBtn.disabled = true;
        this.nextStepBtn.disabled = true;

        this.steps = this.generateSortingSteps([...this.numbers]);
        this.currentStepIndex = 0;

        while (this.currentStepIndex < this.steps.length) {
            await this.executeStep(this.steps[this.currentStepIndex]);
            this.currentStepIndex++;
            await new Promise(resolve => setTimeout(resolve, 1000));
        }

        this.finishSort();
    }

    generateSortingSteps(arr, start = 0, end = arr.length - 1, steps = []) {
        if (start >= end) return steps;

        let pivotIndex = this.partition(arr, start, end, steps);
        this.generateSortingSteps(arr, start, pivotIndex - 1, steps);
        this.generateSortingSteps(arr, pivotIndex + 1, end, steps);

        return steps;
    }

    partition(arr, start, end, steps) {
        const pivot = arr[end];
        let pivotIndex = start;

        steps.push({
            type: 'pivot',
            index: end,
            message: `选择基准值: ${pivot}`
        });

        for (let i = start; i < end; i++) {
            steps.push({
                type: 'compare',
                indices: [i, end],
                message: `比较 ${arr[i]} 和基准值 ${pivot}`
            });

            if (arr[i] <= pivot) {
                if (i !== pivotIndex) {
                    [arr[i], arr[pivotIndex]] = [arr[pivotIndex], arr[i]];
                    steps.push({
                        type: 'swap',
                        indices: [i, pivotIndex],
                        array: [...arr],
                        message: `交换 ${arr[pivotIndex]} 和 ${arr[i]}`
                    });
                }
                pivotIndex++;
            }
        }

        [arr[pivotIndex], arr[end]] = [arr[end], arr[pivotIndex]];
        steps.push({
            type: 'swap',
            indices: [pivotIndex, end],
            array: [...arr],
            message: `将基准值 ${pivot} 放到正确位置`
        });

        return pivotIndex;
    }

    async executeStep(step) {
        const boxes = document.querySelectorAll('.number-box');
        boxes.forEach(box => box.classList.remove('pivot', 'comparing'));

        switch (step.type) {
            case 'pivot':
                boxes[step.index].classList.add('pivot');
                break;
            case 'compare':
                step.indices.forEach(index => {
                    boxes[index].classList.add('comparing');
                });
                break;
            case 'swap':
                await this.animateSwap(
                    boxes[step.indices[0]], 
                    boxes[step.indices[1]]
                );
                this.numbers = [...step.array];
                this.renderNumbers();
                break;
        }

        this.currentStepDisplay.textContent = step.message;
    }

    async animateSwap(element1, element2) {
        return new Promise(resolve => {
            const content1 = element1.textContent;
            const content2 = element2.textContent;
            
            element1.classList.add('swap-right');
            element2.classList.add('swap-left');

            const handleAnimationEnd = () => {
                element1.classList.remove('swap-right');
                element2.classList.remove('swap-left');
                
                element1.textContent = content2;
                element2.textContent = content1;
                
                element1.removeEventListener('animationend', handleAnimationEnd);
                resolve();
            };

            element1.addEventListener('animationend', handleAnimationEnd);
        });
    }

    async nextStep() {
        if (this.isAutoSorting) return;

        if (!this.isRunning) {
            this.isRunning = true;
            this.startSortBtn.disabled = true;
            this.generateNewBtn.disabled = true;
            this.steps = this.generateSortingSteps([...this.numbers]);
            this.currentStepIndex = 0;
        }

        if (this.currentStepIndex < this.steps.length) {
            await this.executeStep(this.steps[this.currentStepIndex]);
            this.currentStepIndex++;
        } else {
            this.finishSort();
        }
    }

    finishSort() {
        this.isRunning = false;
        this.isAutoSorting = false;
        this.startSortBtn.disabled = false;
        this.generateNewBtn.disabled = false;
        this.nextStepBtn.disabled = false;
        this.currentStepDisplay.textContent = '排序完成！';
        
        const boxes = document.querySelectorAll('.number-box');
        boxes.forEach(box => box.classList.add('sorted'));
    }

    reset() {
        this.currentStepIndex = 0;
        this.steps = [];
        this.isRunning = false;
        this.isAutoSorting = false;
        this.startSortBtn.disabled = false;
        this.generateNewBtn.disabled = false;
        this.nextStepBtn.disabled = false;
        this.currentStepDisplay.textContent = '准备开始...';
        this.renderNumbers();
    }
}

// 初始化
window.addEventListener('DOMContentLoaded', () => {
    const game = new QuickSort();
    game.generateNumbers();
}); 